package com.xge.business.fragment

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isGone
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.lxj.xpopup.XPopup
import com.necer.painter.InnerPainter
import com.tencent.mmkv.MMKV
import com.xge.business.DialogAddContent
import com.xge.business.LunarActivity
import com.xge.business.QueryActivity
import com.xge.business.bean.JokeBean
import com.xge.business.bean.MemoBean
import com.xge.business.dao.MeMoDao
import com.xge.business.databinding.FragmentCalendarBinding
import com.xge.business.db.AppDatabase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.URLEncoder
import java.time.LocalDate
import java.time.format.DateTimeFormatter


class CalendarFragment : Fragment() {

    private lateinit var binding: FragmentCalendarBinding


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        binding = FragmentCalendarBinding.inflate(inflater, container, false)
        return binding.root
    }

    var slectDate: String = ""
    private var selectedDates = ArrayList<String>()
    private var selectAll = ArrayList<MemoBean>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val db = AppDatabase.getInstance(requireContext())
        val memoDao = db.userDao()

        queryJokeData()

        val innerPainter = binding.nCalendar.calendarPainter as InnerPainter

        val formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-M-d"))
        queryMemo(memoDao, innerPainter, formattedDate)

        binding.nCalendar.setOnCalendarChangedListener { year, month, localDate, dateChangeBehavior ->
            binding.tvMemo.isGone = true
            binding.tvMemoTitle.isGone = true
            slectDate =
                (localDate.year).toString() + "-" + (localDate.monthValue).toString() + "-" + (localDate.dayOfMonth).toString()
            binding.tvWeek.text = formatWeekday(localDate.dayOfWeek.value)
            binding.tvYear.text = "${year}年"
            binding.tvMonth.text = month.toString()

            queryMemo(memoDao, innerPainter, slectDate)
            queryJokeData()
        }
        binding.tvToDay.setOnClickListener {
            binding.nCalendar.toToday()
        }
        binding.ivAdd.setOnClickListener {
            val addDialog = DialogAddContent(requireContext())
            addDialog.onSubmitClick = { content ->
                val memo = MemoBean(time = slectDate, content = content)
                lifecycleScope.launch {
                    memoDao.insert(memo)
                    queryMemo(memoDao, innerPainter, slectDate)
                    addDialog.dismiss()
                }
            }
            XPopup.Builder(requireContext()).isDestroyOnDismiss(true).asCustom(addDialog).show()
        }

        binding.ivMenu.setOnClickListener {
            XPopup.Builder(context)
                .atView(it) // 依附于所点击的View，内部会自动判断在上方或者下方显示
                .asAttachList(
                    arrayOf("今日黄历", "星座查询"),
                    intArrayOf()
                ) { position, text ->
                    if(position == 0){
                        LunarActivity.start(requireContext())
                    }else if(position == 1){
                        startActivity(Intent(requireContext(), QueryActivity::class.java))
                    }
                }
                .show()
        }

    }

    private fun queryMemo(memoDao: MeMoDao, innerPainter: InnerPainter, time: String) {
        lifecycleScope.launch {
            memoDao.getAll()
            selectAll = memoDao.getAll() as ArrayList<MemoBean>
            selectAll.forEach {
                selectedDates.add(it.time)
            }

            val bean = selectAll.find { it.time == time }
            if (bean != null) {
                binding.tvMemo.isGone = false
                binding.tvMemoTitle.isGone = false
                binding.tvMemo.text = bean.content
            }
            innerPainter.setPointList(selectedDates)
        }

    }

    fun formatWeekday(day: Int): String {
        val weekDays = mapOf(
            1 to "周一",
            2 to "周二",
            3 to "周三",
            4 to "周四",
            5 to "周五",
            6 to "周六",
            7 to "周日"
        )
        return weekDays[day] ?: "未知"
    }

    private fun queryJokeData() {
        lifecycleScope.launch {
            val url = "https://apis.tianapi.com/joke/index"
            val params = mapOf(
                "key" to "8112b172e5582ef9a754a0ee751404ba",
                "num" to "1",
            )
            val json = makeGetRequestWithParams(url, params)
            val jokeBean = Gson().fromJson(json, JokeBean::class.java)
            if (jokeBean.code == 200) {
                if (!jokeBean.result?.list.isNullOrEmpty()) {
                    val bean = jokeBean.result?.list?.get(0)
                    binding.tvJoke.text = bean?.content
                }
            } else {
                Toast.makeText(requireContext(), "网络请求失败", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private suspend fun makeGetRequestWithParams(
        url: String, params: Map<String, String>
    ): String? {
        return withContext(Dispatchers.IO) {
            try {
                // 拼接参数
                val fullUrl = buildUrlWithParams(url, params)

                val client = OkHttpClient()

                val request = Request.Builder().url(fullUrl).build()

                val response = client.newCall(request).execute()
                response.body?.string()
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }
    }

    private fun buildUrlWithParams(baseUrl: String, params: Map<String, String>): String {
        val paramString = params.map {
            "${URLEncoder.encode(it.key, "UTF-8")}=${URLEncoder.encode(it.value, "UTF-8")}"
        }.joinToString("&")
        return "$baseUrl?$paramString"
    }

    companion object {
        fun newInstance(): CalendarFragment {
            val args = Bundle()
            val fragment = CalendarFragment()
            fragment.arguments = args
            return fragment
        }
    }
}